package com.kye.express.business.welfare_integral;

import android.os.Bundle;
import android.support.annotation.Nullable;

import com.kye.base.Logger;
import com.kye.base.utils.GsonUtils;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.IView;
import com.kye.express.databinding.ActivityIntegralCenterBinding;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.UserSession;
import com.kye.model.base.PageInfo;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.integral.IntegralHeaderBean;
import com.kye.model.bean.integral.IntegralRecordEmptyBean;
import com.kye.model.bean.integral.IntegralRecordExchangeRecordBean;
import com.kye.model.bean.integral.IntegralRecordExchangeResultBean;
import com.kye.model.bean.integral.IntegralRecordObtainRecordBean;
import com.kye.model.bean.integral.IntegralRecordObtainResultBean;
import com.kye.model.bean.integral.IntegralRecordStatusBean;
import com.kye.model.bean.integral.IntegralRecordType;
import com.kye.model.bean.integral.IntegralUpdateByUser;
import com.kye.model.bean.integral.IntegralUserBean;
import com.kye.model.bean.integral.request.RequestIntegralExchangeRecords;
import com.kye.model.bean.integral.request.RequestIntegralObtainRecords;
import com.kye.model.bean.integral.request.RequestUpdateIntegralByUser;
import com.kye.model.bean.integral.request.RequestUserIntegral;
import com.kye.model.bean.user.User;
import com.kye.model.datasource.IntegralDataSource;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleObserver;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.SingleSource;
import io.reactivex.SingleTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Function3;
import io.reactivex.schedulers.Schedulers;


public interface IntegralCenterContract {

    interface IntegralCenterView extends IView {

        void onUser(User userInfo);

        ActivityIntegralCenterBinding getBinding();

        void refreshIntegralWithExchangeDataViews(List<Object> objects);

        void refreshIntegralWithObtainDataViews(List<Object> objects);

        void enableLoadMore();

        void disableLoadMore();

        void enableRefresh();

        void disableRefresh();

        IntegralRecordType getRecordType();

        void showIntegralObtainData(ArrayList<Object> objects);

        void showIntegralExchangeData(ArrayList<Object> objects);

        void setRecordType(IntegralRecordType recordType);

        void loadMoreIntegralExchangeData(List<Object> integralListWithExchangeDatas, List<Object> exchangeDatas);

        void updateQueryIntegralObtainData(ArrayList<Object> integralListWithObtainDatas, int oldSize);

        void showLoading();

        void dismissLoading();

        void updateIntegralByUserSuccess(OpenApiResult<IntegralUpdateByUser> result, IntegralHeaderBean integralHeaderBean);

        void updateIntegralByUserFailed(OpenApiResult<IntegralUpdateByUser> result);

        void updateIntegralByUserFailed(String message);

        void showLoadingDialog();

        void dimissLoadingDialog();

    }

    class IntegralCenterPresenter extends BasePresenter<IntegralCenterView> {

        private String TAG_USER_INFO = "TAG_USER_INFO";
        private IntegralDataSource dataSource;
        private Observable<User> userObservable;
        private User userInfo;
        private PageInfo pageInfoExchange;

        private ArrayList<Object> integralListWithExchangeDatas;
        private ArrayList<Object> integralListWithObtainDatas;
        private IntegralHeaderBean integralHeaderBean; // todo : 头部积分信息
        private IntegralRecordStatusBean integralRecordStatusBean; // todo : 状态切换
        private ArrayList<IntegralRecordExchangeRecordBean> integralRecordExchangeRecordBeans;
        private ArrayList<IntegralRecordObtainRecordBean> integralRecordObtainRecordBeans;
        private IntegralRecordEmptyBean integralRecordEmptyBean;

        private Disposable refreshHeaderExchangeDisposable;
        private Disposable refreshHeaderObtainDisposable;
        private Disposable loadMoreExchnageDisposable;

        public IntegralCenterPresenter() {
            dataSource = new IntegralDataSource();
            pageInfoExchange = new PageInfo();
        }

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            if (savedInstanceState != null) {
                userInfo = (User) savedInstanceState.getSerializable(TAG_USER_INFO);
            }
        }

        @Override
        public void onSaveInstanceState(Bundle outState) {
            if (outState != null) {
                outState.putSerializable(TAG_USER_INFO, userInfo);
            }
        }

        @Override
        public void bind(IntegralCenterView view) {
            super.bind(view);
            userObservable = UserSession.getInstance()
                    .getUserForRx()
                    .compose(getView().<User>bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread());
        }

        /**
         * todo : 获取用户数据回调，开始获取积分数据
         */
        public void getUserInfo() {
            userObservable
                    .subscribe(new Consumer<User>() {
                        @Override
                        public void accept(User user) throws Exception {
                            userInfo = user;
                            getView().onUser(user);
                            if (user.isLogin()) {
                                /**
                                 * 用户已经登录，加载用户的积分相关数据
                                 */
                                getView().getBinding().statusLayout.showLoadingView();
                            } else {
                                /**
                                 * 用户没有登录显示错误界面，一般在进入当前积分中心界面之前就做登录拦截
                                 */
                                getView().getBinding().statusLayout.showErrorServerView();
                            }
                        }
                    });
        }

        public Observable<User> getUserObservable() {
            return userObservable;
        }

        /**
         * 将具体类型转成 List<Object>
         *
         * @param tClass
         * @param <T>
         * @return
         */
        private <T> SingleTransformer<List<T>, List<Object>> getListTransformer(Class<T> tClass) {
            return new SingleTransformer<List<T>, List<Object>>() {
                @Override
                public SingleSource<List<Object>> apply(Single<List<T>> upstream) {
                    return
                            upstream.map(new Function<List<T>, List<Object>>() {
                                @Override
                                public List<Object> apply(List<T> ts) throws Exception {
                                    List<Object> ss = new ArrayList<>();
                                    for (T t : ts) {
                                        ss.add(t);
                                    }
                                    return ss;
                                }
                            });
                }
            };
        }

        /**
         * 将具体类型转成 Object
         *
         * @param tClass
         * @param <T>
         * @return
         */
        private <T> SingleTransformer<T, Object> getItemTransformer(Class<T> tClass) {
            return new SingleTransformer<T, Object>() {
                @Override
                public SingleSource<Object> apply(Single<T> upstream) {
                    return upstream.map(new Function<T, Object>() {
                        @Override
                        public Object apply(T t) throws Exception {
                            return t;
                        }
                    });
                }
            };
        }

        /**
         * 获取头部用于积分信息
         *
         * @return
         */
        public Single<Object> getUserIntegralInfoSingle() {
            return Single.just(new RequestUserIntegral())
                    .observeOn(Schedulers.io())
                    .doOnSuccess(new Consumer<RequestUserIntegral>() {
                        @Override
                        public void accept(RequestUserIntegral requestUserIntegral) throws Exception {
                            requestUserIntegral.setPhone(userInfo.getPhone());
                        }
                    })
                    .flatMap(new Function<RequestUserIntegral, SingleSource<OpenApiResult<IntegralUserBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralUserBean>> apply(RequestUserIntegral requestUserIntegral) throws Exception {
                            return dataSource
                                    .getUserIntegral(requestUserIntegral)
                                    .compose(getView().<OpenApiResult<IntegralUserBean>>bindToLifecycleDestroy());
                        }
                    })
                    .map(new Function<OpenApiResult<IntegralUserBean>, IntegralHeaderBean>() {
                        @Override
                        public IntegralHeaderBean apply(OpenApiResult<IntegralUserBean> result) throws Exception {
                            if (result != null && result.isSuccess()) {
                                if (IntegralCenterPresenter.this.integralHeaderBean != null) {
                                    IntegralCenterPresenter.this.integralHeaderBean.setIntegralUserBean(result.getData());

                                } else {
                                    IntegralHeaderBean integralHeaderBean = new IntegralHeaderBean(result.getData());
                                    IntegralCenterPresenter.this.integralHeaderBean = integralHeaderBean;
                                }
                                /**
                                 * 更新头部信息
                                 */
                                if (integralListWithExchangeDatas != null && integralListWithExchangeDatas.size() > 0) {
                                    integralListWithExchangeDatas.set(0, IntegralCenterPresenter.this.integralHeaderBean);
                                }
                                if (integralListWithObtainDatas != null && integralListWithObtainDatas.size() > 0) {
                                    integralListWithObtainDatas.set(0, IntegralCenterPresenter.this.integralHeaderBean);
                                }
                            } else {
                                integralHeaderBean = new IntegralHeaderBean();
                            }
                            return integralHeaderBean;
                        }
                    })
                    // todo : 错误返回默认对象
                    .onErrorReturn(new Function<Throwable, IntegralHeaderBean>() {
                        @Override
                        public IntegralHeaderBean apply(Throwable throwable) throws Exception {
                            if (integralHeaderBean != null) {
                                return integralHeaderBean;
                            }
                            return new IntegralHeaderBean(new IntegralUserBean());
                        }
                    })
                    .compose(getItemTransformer(IntegralHeaderBean.class));
        }

        /**
         * 获取用户兑换信息，刷新，获取第一页数据
         *
         * @return
         */
        public Single<List<Object>> refreshIntegralExchangeListSingle() {
            return Single.just(new RequestIntegralExchangeRecords())
                    .observeOn(Schedulers.io())
                    .doOnSuccess(new Consumer<RequestIntegralExchangeRecords>() {
                        @Override
                        public void accept(RequestIntegralExchangeRecords requestIntegralExchangeRecords) throws Exception {
                            requestIntegralExchangeRecords.setPhone(userInfo.getPhone());
                            requestIntegralExchangeRecords.setPageIndex(PageInfo.INDEX_DEFAULT);
                            requestIntegralExchangeRecords.setPageSize(pageInfoExchange.getPageSize());
                        }
                    })
                    .flatMap(new Function<RequestIntegralExchangeRecords, SingleSource<OpenApiResult<IntegralRecordExchangeResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralRecordExchangeResultBean>> apply(RequestIntegralExchangeRecords requestIntegralExchangeRecords) throws Exception {
                            return dataSource.getIntegralExchangeRecords(requestIntegralExchangeRecords)
                                    .compose(getView().<OpenApiResult<IntegralRecordExchangeResultBean>>bindToLifecycleDestroy());
                        }
                    })
                    .map(new Function<OpenApiResult<IntegralRecordExchangeResultBean>, List<IntegralRecordExchangeRecordBean>>() {
                        @Override
                        public List<IntegralRecordExchangeRecordBean> apply(OpenApiResult<IntegralRecordExchangeResultBean> result) throws Exception {
                            List<IntegralRecordExchangeRecordBean> integralRecordExchangeRecordBeans;
                            if (result != null && result.isSuccess()) {
                                integralRecordExchangeRecordBeans = result.getData().getRetDatas();
                                // 成功重置页数
                                pageInfoExchange.resetPage();
                            } else {
                                integralRecordExchangeRecordBeans = new ArrayList<>();
                            }
                            return integralRecordExchangeRecordBeans;
                        }
                    })
                    // todo : 错误返默认列表
                    .onErrorReturn(new Function<Throwable, List<IntegralRecordExchangeRecordBean>>() {
                        @Override
                        public List<IntegralRecordExchangeRecordBean> apply(Throwable throwable) throws Exception {
                            return new ArrayList<>();
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSuccess(new Consumer<List<IntegralRecordExchangeRecordBean>>() {
                        @Override
                        public void accept(List<IntegralRecordExchangeRecordBean> integralRecordExchangeRecordBeans) throws Exception {
                            if (integralRecordExchangeRecordBeans.size() <= 0) {
                                getView().disableLoadMore();
                            }
                        }
                    })
                    .observeOn(Schedulers.io())
                    .compose(getListTransformer(IntegralRecordExchangeRecordBean.class))
                    .doOnSuccess(new Consumer<List<Object>>() {
                        @Override
                        public void accept(List<Object> objects) throws Exception {
                            if (objects.size() <= 0) {
                                /**
                                 * show empty
                                 */
                                objects.add(new IntegralRecordEmptyBean());
                            }
                        }
                    });
        }

        /**
         * 获取用户兑换信息，加载更多
         *
         * @return
         */
        public Single<List<Object>> loadMoreIntegralExchangeListSingle() {
            return Single.just(new RequestIntegralExchangeRecords())
                    .observeOn(Schedulers.io())
                    .doOnSuccess(new Consumer<RequestIntegralExchangeRecords>() {
                        @Override
                        public void accept(RequestIntegralExchangeRecords requestIntegralExchangeRecords) throws Exception {
                            requestIntegralExchangeRecords.setPhone(userInfo.getPhone());
                            requestIntegralExchangeRecords.setPageIndex(pageInfoExchange.getPageIndex() + 1);
                            requestIntegralExchangeRecords.setPageSize(pageInfoExchange.getPageSize());
                        }
                    })
                    .flatMap(new Function<RequestIntegralExchangeRecords, SingleSource<OpenApiResult<IntegralRecordExchangeResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralRecordExchangeResultBean>> apply(RequestIntegralExchangeRecords requestIntegralExchangeRecords) throws Exception {
                            return dataSource.getIntegralExchangeRecords(requestIntegralExchangeRecords)
                                    .compose(getView().<OpenApiResult<IntegralRecordExchangeResultBean>>bindToLifecycleDestroy());
                        }
                    })
                    .map(new Function<OpenApiResult<IntegralRecordExchangeResultBean>, List<IntegralRecordExchangeRecordBean>>() {
                        @Override
                        public List<IntegralRecordExchangeRecordBean> apply(OpenApiResult<IntegralRecordExchangeResultBean> result) throws Exception {
                            if (result != null && result.isSuccess()) {
                                List<IntegralRecordExchangeRecordBean> tempDatas = null;
                                // global datas
                                tempDatas.addAll(result.getData().getRetDatas());
                                // 成功页数加一
                                pageInfoExchange.increasePage();
                            } else {

                            }
                            return integralRecordExchangeRecordBeans;
                        }
                    })
                    // todo : 错误返默认列表
                    .onErrorReturn(new Function<Throwable, List<IntegralRecordExchangeRecordBean>>() {
                        @Override
                        public List<IntegralRecordExchangeRecordBean> apply(Throwable throwable) throws Exception {
                            return new ArrayList<>();
                        }
                    })
                    .compose(getListTransformer(IntegralRecordExchangeRecordBean.class));
        }

        /**
         * 刷新用户获取记录信息, 默认获取当前IntegralRecordStatusBean的时间记录 from and to
         *
         * @return
         */
        public Single<List<Object>> refreshIntegralObtainListSingle() {
            return Single.just(new RequestIntegralObtainRecords())
                    .observeOn(Schedulers.io())
                    .doOnSuccess(new Consumer<RequestIntegralObtainRecords>() {
                        @Override
                        public void accept(RequestIntegralObtainRecords requestIntegralObtainRecords) throws Exception {
                            if (integralRecordStatusBean == null) {
                                integralRecordStatusBean = IntegralRecordStatusBean.newInstance();
                            }
                            /**
                             * todo : 更新UI操作,只能选择某一天时间
                             */
//                            requestIntegralObtainRecords.setStartTime(integralRecordStatusBean.getDateFrom());
//                            requestIntegralObtainRecords.setEndTime(integralRecordStatusBean.getDateTo());
                            requestIntegralObtainRecords.setStartTime(integralRecordStatusBean.getDate());
                            requestIntegralObtainRecords.setEndTime(integralRecordStatusBean.getDate());
                        }
                    })
                    .doOnSuccess(new Consumer<RequestIntegralObtainRecords>() {
                        @Override
                        public void accept(RequestIntegralObtainRecords requestIntegralObtainRecords) throws Exception {
                            requestIntegralObtainRecords.setPhone(userInfo.getPhone());
                        }
                    })
                    .flatMap(new Function<RequestIntegralObtainRecords, SingleSource<OpenApiResult<IntegralRecordObtainResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralRecordObtainResultBean>> apply(RequestIntegralObtainRecords requestIntegralObtainRecords) throws Exception {
                            return dataSource.getIntegralObtainRecords(requestIntegralObtainRecords)
                                    .compose(getView().<OpenApiResult<IntegralRecordObtainResultBean>>bindToLifecycleDestroy());
                        }
                    })
                    .map(new Function<OpenApiResult<IntegralRecordObtainResultBean>, List<IntegralRecordObtainRecordBean>>() {
                        @Override
                        public List<IntegralRecordObtainRecordBean> apply(OpenApiResult<IntegralRecordObtainResultBean> result) throws Exception {
                            List<IntegralRecordObtainRecordBean> integralRecordObtainResultBeans;
                            if (result != null && result.isSuccess()) {
                                integralRecordObtainResultBeans = result.getData().getDatas();
                            } else {
                                integralRecordObtainResultBeans = new ArrayList<>();
                            }
                            return integralRecordObtainResultBeans;
                        }
                    })
                    // todo : 错误返默认列表
                    .onErrorReturn(new Function<Throwable, List<IntegralRecordObtainRecordBean>>() {
                        @Override
                        public List<IntegralRecordObtainRecordBean> apply(Throwable throwable) throws Exception {
                            return new ArrayList<>();
                        }
                    })
                    .compose(getListTransformer(IntegralRecordObtainRecordBean.class))
                    .doOnSuccess(new Consumer<List<Object>>() {
                        @Override
                        public void accept(List<Object> objects) throws Exception {
                            if (objects.size() <= 0) {
                                /**
                                 * show empty
                                 */
                                objects.add(new IntegralRecordEmptyBean());
                            }
                        }
                    });
        }

        public Single<Object> getTabItemSingle() {
            return
                    Single
                            .create(new SingleOnSubscribe<IntegralRecordStatusBean>() {
                                @Override
                                public void subscribe(SingleEmitter<IntegralRecordStatusBean> e) throws Exception {
                                    if (integralRecordStatusBean == null) {
                                        integralRecordStatusBean = IntegralRecordStatusBean.newInstance();
                                    }
                                    e.onSuccess(integralRecordStatusBean);
                                }
                            })
                            .compose(getView().<IntegralRecordStatusBean>bindToLifecycleDestroy())
                            .subscribeOn(Schedulers.io())
                            .observeOn(Schedulers.io())
                            .compose(getItemTransformer(IntegralRecordStatusBean.class));
        }

        /**
         * 刷新数据,头部 兑换
         */
        public void refreshIntegralHeaderAndExchangeData() {
            Single
                    .zip(getUserIntegralInfoSingle(), refreshIntegralExchangeListSingle(), getTabItemSingle(), new Function3<Object, List<Object>, Object, List<Object>>() {
                        @Override
                        public List<Object> apply(Object integralUserBean, List<Object> integralRecordExchangeRecordBeans, Object integralRecordStatusBean) throws Exception {
                            List<Object> dataList = new ArrayList<>();
                            // 0:header
                            dataList.add(integralUserBean);
                            // 1:tab
                            IntegralRecordStatusBean integralRecordStatusBean1 = (IntegralRecordStatusBean) integralRecordStatusBean;
                            integralRecordStatusBean1.setRecordType(IntegralRecordType.TYPE_EXCHANGE);
                            dataList.add(integralRecordStatusBean);
                            // 2..datalist
                            dataList.addAll(integralRecordExchangeRecordBeans);
                            return dataList;
                        }
                    })
                    .doOnSuccess(new Consumer<List<Object>>() {
                        @Override
                        public void accept(List<Object> objects) throws Exception {
                            integralListWithExchangeDatas = (ArrayList<Object>) objects;
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<Object>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            refreshHeaderExchangeDisposable = d;
                        }

                        @Override
                        public void onSuccess(List<Object> objects) {
                            Logger.d("onsuccess : " + GsonUtils.toJsonString(objects, true));
                            getView().refreshIntegralWithExchangeDataViews(objects);
                        }

                        @Override
                        public void onError(Throwable e) {
                            Logger.d("onError : " + e.getMessage());
                        }
                    });
        }

        /**
         * 刷新数据,头部 获取
         */
        public void refreshIntegralHeaderAndObtainData() {
            Single
                    .zip(getUserIntegralInfoSingle(), refreshIntegralObtainListSingle(), getTabItemSingle(), new Function3<Object, List<Object>, Object, List<Object>>() {
                        @Override
                        public List<Object> apply(Object integralUserBean, List<Object> integralRecordExchangeRecordBeans, Object integralRecordStatusBean) throws Exception {
                            List<Object> dataList = new ArrayList<>();
                            // 0:header
                            dataList.add(integralUserBean);
                            // 1:tab
                            IntegralRecordStatusBean integralRecordStatusBean1 = (IntegralRecordStatusBean) integralRecordStatusBean;
                            integralRecordStatusBean1.setRecordType(IntegralRecordType.TYPE_OBTAIN);
                            dataList.add(integralRecordStatusBean);
                            // 2..datalist
                            dataList.addAll(integralRecordExchangeRecordBeans);
                            return dataList;
                        }
                    })
                    .doOnSuccess(new Consumer<List<Object>>() {
                        @Override
                        public void accept(List<Object> objects) throws Exception {
                            integralListWithObtainDatas = (ArrayList<Object>) objects;
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<Object>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            refreshHeaderObtainDisposable = d;
                            getView().showLoadingDialog();
                        }

                        @Override
                        public void onSuccess(List<Object> objects) {
                            Logger.d("onsuccess : " + GsonUtils.toJsonString(objects, true));
                            getView().refreshIntegralWithObtainDataViews(objects);
                            getView().dimissLoadingDialog();
                        }

                        @Override
                        public void onError(Throwable e) {
                            Logger.d("onError : " + e.getMessage());
                            getView().dimissLoadingDialog();
                        }
                    });
        }

        private Single<List<Object>> queryIntegralObtainDataSingle() {
            return Single.just(new RequestIntegralObtainRecords())
                    .observeOn(Schedulers.io())
                    .doOnSuccess(new Consumer<RequestIntegralObtainRecords>() {
                        @Override
                        public void accept(RequestIntegralObtainRecords requestIntegralObtainRecords) throws Exception {
                            if (integralRecordStatusBean == null) {
                                integralRecordStatusBean = IntegralRecordStatusBean.newInstance();
                            }
                            requestIntegralObtainRecords.setStartTime(integralRecordStatusBean.getDateFrom());
                            requestIntegralObtainRecords.setEndTime(integralRecordStatusBean.getDateTo());
                        }
                    })
                    .doOnSuccess(new Consumer<RequestIntegralObtainRecords>() {
                        @Override
                        public void accept(RequestIntegralObtainRecords requestIntegralObtainRecords) throws Exception {
                            requestIntegralObtainRecords.setPhone(userInfo.getPhone());
                        }
                    })
                    .flatMap(new Function<RequestIntegralObtainRecords, SingleSource<OpenApiResult<IntegralRecordObtainResultBean>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralRecordObtainResultBean>> apply(RequestIntegralObtainRecords requestIntegralObtainRecords) throws Exception {
                            return dataSource.getIntegralObtainRecords(requestIntegralObtainRecords)
                                    .compose(getView().<OpenApiResult<IntegralRecordObtainResultBean>>bindToLifecycleDestroy());
                        }
                    })
                    .map(new Function<OpenApiResult<IntegralRecordObtainResultBean>, List<IntegralRecordObtainRecordBean>>() {
                        @Override
                        public List<IntegralRecordObtainRecordBean> apply(OpenApiResult<IntegralRecordObtainResultBean> result) throws Exception {
                            List<IntegralRecordObtainRecordBean> integralRecordObtainResultBeans;
                            if (result != null && result.isSuccess()) {
                                integralRecordObtainResultBeans = result.getData().getDatas();
                            } else {
                                integralRecordObtainResultBeans = new ArrayList<>();
                            }
                            return integralRecordObtainResultBeans;
                        }
                    })
                    // todo : 错误返默认列表
                    .onErrorReturn(new Function<Throwable, List<IntegralRecordObtainRecordBean>>() {
                        @Override
                        public List<IntegralRecordObtainRecordBean> apply(Throwable throwable) throws Exception {
                            return new ArrayList<>();
                        }
                    })
                    .compose(getListTransformer(IntegralRecordObtainRecordBean.class));
        }

        /**
         * 刷新数据,头部 获取
         */
        private void refreshIntegralObtainData() {
            Single<Object> integralUserObservable = Single.just(integralHeaderBean).compose(getItemTransformer(IntegralHeaderBean.class));
            Single<Object> integralTabObservable = Single.just(integralRecordStatusBean).compose(getItemTransformer(IntegralRecordStatusBean.class));
            Single
                    .zip(integralUserObservable, integralTabObservable, queryIntegralObtainDataSingle(), new Function3<Object, Object, List<Object>, List<Object>>() {
                        @Override
                        public List<Object> apply(Object userIntegralInfo, Object integralTab, List<Object> integralObtainDatas) throws Exception {
                            List<Object> integralListWithObtainDatasNew = new ArrayList<>();
                            integralListWithObtainDatasNew.clear();
                            integralListWithObtainDatasNew.add(userIntegralInfo);
                            integralListWithObtainDatasNew.add(integralTab);
                            integralListWithObtainDatasNew.addAll(integralObtainDatas);
                            return integralListWithObtainDatasNew;
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .compose(getView().<List<Object>>bindToLifecycleDestroy())
                    .subscribe(new SingleObserver<List<Object>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(List<Object> objects) {
                            int size = integralListWithObtainDatas.size();
                            int sizeNew = objects.size();
                            integralListWithObtainDatas = (ArrayList<Object>) objects;
                            getView().updateQueryIntegralObtainData(integralListWithObtainDatas, size);
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });
        }

        /**
         * todo : 当前只开放兑换记录的刷新功能，获取记录暂不提供刷新
         */
        public void refreshData() {
            IntegralRecordType type = null;
            if (integralRecordStatusBean != null) {
                type = integralRecordStatusBean.getRecordType();
            } else {
                type = getView().getRecordType();
            }
            switch (type) {
                case TYPE_EXCHANGE: {
                    /**
                     * todo : only this way
                     */
                    refreshIntegralHeaderAndExchangeData();
                    break;
                }
                case TYPE_OBTAIN: {
                    refreshIntegralHeaderAndObtainData();
                    break;
                }
            }
        }

        /**
         * 切换 兑换和获取记录的tab
         * @param position
         * @param item
         */
        public void switchToTab(int position, IntegralRecordStatusBean item) {
            switch (position) {
                case 0:
                    getView().enableRefresh();
                    if (integralListWithExchangeDatas.size() - 2 > pageInfoExchange.getPageSize()) {
                        getView().enableLoadMore();
                    }
                    getView().setRecordType(IntegralRecordType.TYPE_EXCHANGE);
                    if (integralListWithExchangeDatas == null) {
                        // 首次加载, 刷新数据,包括头部
                        refreshIntegralHeaderAndExchangeData();
                    } else {
                        /**
                         * 显示兑换记录数据
                         */
                        IntegralRecordStatusBean statusBean = (IntegralRecordStatusBean) integralListWithExchangeDatas.get(1);
                        statusBean.setRecordType(IntegralRecordType.TYPE_EXCHANGE);
                        showIntegralExchangeData();
                    }
                    break;
                case 1:
                    getView().disableRefresh();
                    getView().disableLoadMore();
                    getView().setRecordType(IntegralRecordType.TYPE_OBTAIN);
                    if (integralListWithObtainDatas == null) {
                        // 首次加载, 刷新数据,包括头部
                        refreshIntegralHeaderAndObtainData();
                    } else {
                        /**
                         * 显示获取记录数据
                         */
                        IntegralRecordStatusBean statusBean = (IntegralRecordStatusBean) integralListWithObtainDatas.get(1);
                        statusBean.setRecordType(IntegralRecordType.TYPE_OBTAIN);
                        showIntegralObtainData();
                    }
                    break;
                default:
                    throw new IllegalStateException("switchToTab");
            }
        }

        private void showIntegralObtainData() {
            Single.just(integralListWithObtainDatas)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<ArrayList<Object>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(ArrayList<Object> objects) {
                            getView().showIntegralObtainData(objects);
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });
        }

        private void showIntegralExchangeData() {
            Single.just(integralListWithExchangeDatas)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<ArrayList<Object>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(ArrayList<Object> objects) {
                            getView().showIntegralExchangeData(objects);
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });
        }

        /**
         * 加载更多兑换记录信息数据
         */
        public void loadMoreExchangeData() {
            loadMoreIntegralExchangeListSingle()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnSuccess(new Consumer<List<Object>>() {
                        @Override
                        public void accept(List<Object> objects) throws Exception {
//                            integralListWithExchangeDatas.addAll(objects);
                        }
                    })
                    .subscribe(new SingleObserver<List<Object>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            loadMoreExchnageDisposable = d;
                        }

                        @Override
                        public void onSuccess(List<Object> objects) {
                            getView().loadMoreIntegralExchangeData(integralListWithExchangeDatas, objects);
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });

        }

        public void updateIntegralByUser(IntegralHeaderBean item) {
            Single.just(new RequestUpdateIntegralByUser(null, userInfo.getPhone()))
                    .flatMap(new Function<RequestUpdateIntegralByUser, SingleSource<OpenApiResult<IntegralUpdateByUser>>>() {
                        @Override
                        public SingleSource<OpenApiResult<IntegralUpdateByUser>> apply(RequestUpdateIntegralByUser requestUpdateIntegralByUser) throws Exception {
                            return dataSource.updateIntegralByUser(requestUpdateIntegralByUser)
                                    .compose(getView().<OpenApiResult<IntegralUpdateByUser>>bindToLifecycleDestroy());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<IntegralUpdateByUser>() {
                        @Override
                        public void onLoading(Disposable d) {
                            getView().showLoading();
                        }

                        @Override
                        public void onSuccess(OpenApiResult<IntegralUpdateByUser> result, IntegralUpdateByUser integralUpdateByUser) {
                            Logger.d("updateIntegralByUser onSuccess : " + GsonUtils.toJsonString(result, true));
                            getView().updateIntegralByUserSuccess(result, integralHeaderBean);
                        }

                        @Override
                        public void onApiError(OpenApiResult<IntegralUpdateByUser> result, int code, String msg) {
                            Logger.d("updateIntegralByUser onApiError : " + msg);
                            getView().updateIntegralByUserFailed(result);
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                            Logger.d("updateIntegralByUser onOtherError : " + e.getMessage());
                            getView().updateIntegralByUserFailed(e.getMessage());
                        }

                        @Override
                        public void onLoaded() {
                            getView().dismissLoading();
                        }
                    });
        }


    }

}
